#ifndef __LCD5110_H
#define __LCD5110_H

#include "main.h"
#include "stm32f0xx_hal.h"

#define F(s) (uint8_t *)(s)

//colors
#define WHITE 0
#define BLACK 1
#define INVERT 2
#define GRAY 3

//for extended bitmap function :
#define NOROT 0
#define ROTCCW 1
#define ROT180 2
#define ROTCW 3
#define NOFLIP 0
#define FLIPH 1
#define FLIPV 2
#define FLIPVH 3

#if (DISPLAY_ROT == NO_ROT)||(DISPLAY_ROT == ROT180) //landscape mode
#define LCDWIDTH 84
#define LCDHEIGHT 48
#else //portrait mode
#define LCDWIDTH 48
#define LCDHEIGHT 84
#endif
#define LCDHEIGHT_NOROT 48
#define LCDWIDTH_NOROT 84

#define swap(a, b) { int8_t t = a; a = b; b = t; }
#define max(a,b) (a>b)?a:b
#define min(a,b) (a<b)?a:b


#define PCD8544_POWERDOWN 0x04
#define PCD8544_ENTRYMODE 0x02
#define PCD8544_EXTENDEDINSTRUCTION 0x01

#define PCD8544_DISPLAYBLANK 0x0
#define PCD8544_DISPLAYNORMAL 0x4
#define PCD8544_DISPLAYALLON 0x1
#define PCD8544_DISPLAYINVERTED 0x5

// H = 0
#define PCD8544_FUNCTIONSET 0x20
#define PCD8544_DISPLAYCONTROL 0x08
#define PCD8544_SETYADDR 0x40
#define PCD8544_SETXADDR 0x80
#define PCD8544_SETXADDR 0x80

// H = 1
#define PCD8544_SETTEMP 0x04
#define PCD8544_SETBIAS 0x10
#define PCD8544_SETVOP 0x80


//config
#define DISPLAY_ROT NOROT //set to NOROT, ROTCCW, ROT180 or ROTCW. Can be used to play in portrait mode.
#define ENABLE_BITMAPS 1 //will replace bitmaps with rectangles if disabled
#define ENABLE_GRAYSCALE 1 //allows the use of the GRAY color
#define EXTENDED_NOTE_RANGE 0 //allows the use of notes above A 5... please avoid that they sound really bad


typedef struct
{
	void (*begin)(void);
	void (*command)(uint8_t c);
	void (*data)(uint8_t c);
	uint8_t* (*getBuffer)();

	void (*setContrast)(uint8_t val);
	void (*clear)(void);
	void (*update)();
	void (*setColor)(int8_t c);
	void (*setColor1)(int8_t c, int8_t bg);
	void (*drawPixel)(int8_t x, int8_t y);
	uint8_t (*getPixel)(int8_t x, int8_t y);

	void (*drawLine)(int8_t x0, int8_t y0, int8_t x1, int8_t y1);
	void (*drawFastVLine)(int8_t x, int8_t y, int8_t h);
	void (*drawFastHLine)(int8_t x, int8_t y, int8_t w);
	void (*drawRect)(int8_t x, int8_t y, int8_t w, int8_t h);
	void (*fillRect)(int8_t x, int8_t y, int8_t w, int8_t h);
	void (*fillScreen)(uint8_t color);

	void (*drawCircle)(int8_t x0, int8_t y0, int8_t r);
	void (*drawCircleHelper)(int8_t x0, int8_t y0, int8_t r, uint8_t cornername);
	void (*fillCircle)(int8_t x0, int8_t y0, int8_t r);
	void (*fillCircleHelper)(int8_t x0, int8_t y0, int8_t r, uint8_t cornername, int8_t delta);

	void (*drawTriangle)(int8_t x0, int8_t y0, int8_t x1, int8_t y1, int8_t x2, int8_t y2);
	void (*fillTriangle)(int8_t x0, int8_t y0, int8_t x1, int8_t y1, int8_t x2, int8_t y2);
	void (*drawRoundRect)(int8_t x0, int8_t y0, int8_t w, int8_t h, int8_t radius);
	void (*fillRoundRect)(int8_t x0, int8_t y0, int8_t w, int8_t h, int8_t radius);
	
	void (*drawBitmap)(int8_t x, int8_t y, const uint8_t *bitmap);
	void (*drawBitmap1)(int8_t x, int8_t y, const uint8_t *bitmap, uint8_t rotation, uint8_t flip);
	uint8_t (*getBitmapPixel)(const uint8_t* bitmap, uint8_t x, uint8_t y);
	
	void (*setFont)(const uint8_t* f);
	void (*drawChar)(int8_t x, int8_t y, unsigned char c, uint8_t size);
	size_t (*write)(uint8_t);
	
	size_t (*print)(const uint8_t *dat);
	size_t (*println)(const uint8_t *dat);
	size_t (*printN10)(long n);
	
	uint8_t persistence; //disable clean() at each frame if true
	uint8_t textWrap; // If set, 'wrap' text at right edge of 
	uint8_t fontSize;
	int8_t  cursorX, cursorY;
	uint8_t contrast;
	uint8_t frameCount;
	uint8_t fontWidth, fontHeight;
	
}DisplayStruct;

extern DisplayStruct display;
extern uint8_t font3x3[];
extern uint8_t font3x5[];
extern uint8_t font5x7[];








/***********************内部函数名称****************************/
void user_LcdCommand(uint8_t cmd);
void user_LcdData(uint8_t dat);
void user_LcdsetContrast(uint8_t val);
void user_displayBegin(void);
void user_displayClear(void);
void user_displayUpdate(void);
void user_displayDrawPixel(int8_t x, int8_t y);
uint8_t user_displayGetPixel(int8_t x, int8_t y);
void user_displayDrawFastVLine(int8_t x, int8_t y, int8_t h);
void user_displayDrawFastHLine(int8_t x, int8_t y, int8_t w);
void user_displayDrawPixel(int8_t x, int8_t y);
void user_displaySetColor(int8_t c);
void user_displaySetColor1(int8_t c, int8_t bg);
void user_displayDrawRect(int8_t x, int8_t y, int8_t w, int8_t h);
void user_displayFillRect(int8_t x, int8_t y, int8_t w, int8_t h);
void user_displayFillScreen(uint8_t color);
void user_displayDrawLine(int8_t x0, int8_t y0, int8_t x1, int8_t y1);
void user_displayDrawCircle(int8_t x0, int8_t y0, int8_t r);
void user_displayDrawCircleHelper(int8_t x0, int8_t y0, int8_t r, uint8_t cornername);
void user_displayFillCircle(int8_t x0, int8_t y0, int8_t r);
void user_displayFillCircleHelper(int8_t x0, int8_t y0, int8_t r, uint8_t cornername, int8_t delta);
void user_displayDrawRoundRect(int8_t x, int8_t y, int8_t w,int8_t h, int8_t r);
void user_displayFillRoundRect(int8_t x, int8_t y, int8_t w,int8_t h, int8_t r);
void user_displayDrawTriangle(int8_t x0, int8_t y0,int8_t x1, int8_t y1,int8_t x2, int8_t y2);
void user_displayFillTriangle(int8_t x0, int8_t y0,int8_t x1, int8_t y1,int8_t x2, int8_t y2);
void user_displayDrawBitmap(int8_t x, int8_t y, const uint8_t *bitmap);
uint8_t user_displayGetBitmapPixel(const uint8_t* bitmap, uint8_t x, uint8_t y);
void user_displayDrawBitmap1(int8_t x, int8_t y, const uint8_t *bitmap,uint8_t rotation, uint8_t flip);
void user_displaySetFont(const uint8_t *f);
void user_displayDrawChar(int8_t x, int8_t y, unsigned char c, uint8_t size);
size_t user_displayWrite(uint8_t c);  
uint8_t* user_displayGetBuffer(void);

void user_displaySetCursor(int8_t x,int8_t y);
void user_displaySetFontSize(uint8_t size);
void user_displaySetTextWrap(uint8_t value);

size_t user_displayPrint(const uint8_t *dat);
size_t user_displayPrintln(const uint8_t *dat);
size_t user_displayPrintN10(long n);
size_t user_displayPrintNumber(unsigned long n, uint8_t base);  //n 数字   base进制

#endif

